package com.magnificent.atlantis.server.connection;

import com.magnificent.atlantis.common.Connector;
import com.magnificent.atlantis.common.entity.ServerMeeting;
import com.magnificent.atlantis.common.entity.ServerUser;
import com.magnificent.atlantis.common.entity.messages.ServerMessage;
import com.magnificent.atlantis.common.message.Response;
import com.magnificent.atlantis.common.message.user.UserBaned;
import com.magnificent.atlantis.common.message.user.UserLoginFailed;
import com.magnificent.atlantis.common.message.user.UserLoginSuccesfull;
import com.magnificent.atlantis.server.database.AtlantisDataSource;
import com.magnificent.atlantis.server.database.message.MessageHandler;
import com.magnificent.atlantis.server.event.EventDispatcher;
import com.magnificent.atlantis.server.event.EventType;
import com.magnificent.atlantis.server.event.message.UserLoginEvent;
import com.magnificent.commons.db.datasource.ObjectEntity;
import com.magnificent.commons.utils.crypt.MD5;
import org.hibernate.Session;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * User: Babanin
 * Date: 02.04.2009
 * Time: 11:24:19
 */
public class ServerConnectorImpl implements Connector {
    public Response login(String login, String password) throws RemoteException {
        Session session = AtlantisDataSource.getInstance().getSession();
        ServerUser user = (ServerUser) session.createQuery("from ServerUser where login=\'" + login + "\'").uniqueResult();
        AtlantisDataSource.getInstance().commit();

        String cryptedPassword = MD5.crypt(password);
        if (user.getPassword().equals(cryptedPassword)) {
            if (user.isBaned()) {
                return new UserBaned();
            } else {
                user.setLastUpdate(new Date());

                AtlantisDataSource.getInstance().update(user);
                EventDispatcher.getInstance().postEvent(EventType.LOGIN, new UserLoginEvent(user));

                return new UserLoginSuccesfull((int) user.getId());
            }
        }

        return new UserLoginFailed();
    }

    public List<ServerUser> getUserList() throws RemoteException {
        Session session = AtlantisDataSource.getInstance().getSession();
        List<ServerUser> list = session.createCriteria(ServerUser.class).list();
        AtlantisDataSource.getInstance().commit();

        for (ServerUser user : list) {
            user.setLogin("");
            user.setPassword("");
        }

        return list;
    }

    public List<ServerMessage> getMessages(int userId) throws RemoteException {
        Session session = AtlantisDataSource.getInstance().getSession();
        List<ServerMessage> resultList = new ArrayList<ServerMessage>();

        resultList.addAll(session.createQuery("from ServerTextMessage where userToid=" + userId).list());
        resultList.addAll(session.createQuery("from ServerInviteMessage where userToid=" + userId).list());
        resultList.addAll(session.createQuery("from ServerAcceptMeetingMessage where userToid=" + userId).list());
        resultList.addAll(session.createQuery("from ServerCancelMeetingMessage where userToid=" + userId).list());
//        resultList.addAll(session.createQuery("from ServerUpdateMeetingMessage where userToid=" + userId).list());

        for (ServerMessage message : resultList) {
            session.delete(message);
        }

        AtlantisDataSource.getInstance().commit();
        return resultList;
    }

    public ObjectEntity postMessage(ServerMessage message) throws RemoteException {
        System.out.println(message.toString());
        return MessageHandler.messageReceived(message);
    }

    // Meetings                               
    public List<ServerMeeting> getMeetings(List<Integer> meetingIds) throws RemoteException {
        List<ServerMeeting> result = new ArrayList<ServerMeeting>();
        List<ServerMeeting> meetingList = AtlantisDataSource.getInstance().getBeans(ServerMeeting.class);

        for (ServerMeeting serverMeeting : meetingList) {
            if (meetingIds.contains(serverMeeting.getId())) {
                result.add(serverMeeting);
            }
        }

        return result;
    }

    // Meetings
    public ServerMeeting getMeeting(int meetingId) throws RemoteException {
        return AtlantisDataSource.getInstance().getMeeting(meetingId);
    }
}
